﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using log4net;
using System.Reflection;
using System.Web.UI.HtmlControls;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text.RegularExpressions;
using System.Web;

namespace Cn.Edwon.Web.Validation {
    public class QuickValidator {
        public static ILog iLog = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private static String _Message;
        public class VdType {
            public const String QUERY = "query";
            public const String REQUIRED = "required";
            public const String REGEX = "regex";
            public const String EQUAL = "equal";
            public const String COMPARE = "compare";
            public const String INTEGER = "integer";
            public const String FLOAT = "float";
            public const String EMAIL = "email";
            public const String CHECK = "check";
            public const String MONEY = "money";
            public const String DATETIME = "datetime";
        }
        public static String Message {
            set { }
            get { return _Message; }
        }
        /// <summary>
        /// 配置文件Document对象
        /// </summary>
        public static XmlDocument doc = new XmlDocument();
        /// <summary>
        /// 输出js脚本时，json对象的对象名
        /// </summary>
        public static String OutputVarName = "JSKITVALIDATION";

        public static XmlNode GetForm(String rUrlPattern) {
            XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable());
            xnm.AddNamespace("ns", "urn:edwon-cn:configuration");
            rUrlPattern = (String.IsNullOrEmpty(rUrlPattern)) ? "" : rUrlPattern.ToLower();
            return doc.SelectSingleNode("//ns:validation/ns:form[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='" + rUrlPattern + "']", xnm);
        }
        /// <summary>
        /// 将校验配置转换成json数据
        /// </summary>
        /// <param name="rUrlPattern"></param>
        /// <returns></returns>
        public static String Build2Json(String rUrlPattern) {
            XmlNode form = GetForm(rUrlPattern);
            StringBuilder sb = new StringBuilder();
            sb.Append("var " + OutputVarName + "=[");
            if (form == null) {
                iLog.Debug("没有为当前页面(" + rUrlPattern + ")配置validation内容");
                sb.Append("];");
                return sb.ToString() ;
            }
            String clientPrefix = "";
            if (form.Attributes["client-prefix"] != null) {
                clientPrefix = form.Attributes["client-prefix"].Value;
            }
            for (int i = 0; i < form.ChildNodes.Count; i++) {
                XmlNode node = form.ChildNodes[i];
                if (i > 0) {
                    sb.Append(",");
                }
                sb.Append("[");
                sb.Append("\"" + node.Attributes["type"].Value + "\"");
                sb.Append(",\"#" + clientPrefix + node.Attributes["id"].Value + "\"");
                sb.Append(",\"" + node.InnerText + "\"");
                if (node.Attributes["pattern"] != null) {
                    sb.Append(",\"" + node.Attributes["pattern"].Value + "\"");
                } else {
                    sb.Append(",\"\"");
                }
                if (node.Attributes["compare"] != null) {
                    sb.Append(",\"#" + clientPrefix + node.Attributes["compare"].Value + "\"");
                } else {
                    sb.Append(",\"\"");
                }
                if (node.Attributes["express"] != null) {
                    sb.Append(",\"" + node.Attributes["express"].Value + "\"");
                } else {
                    sb.Append(",\"\"");
                }
                sb.Append("]");
            }
            sb.Append("];");
            return sb.ToString();
        }

        /// <summary>
        /// 校验当前页面
        /// </summary>
        /// <param name="rRequest"></param>
        /// <param name="rContainer"></param>
        /// <returns></returns>
        public static Boolean Execute(HttpRequest rRequest, Control rContainer) {
            try {
                return Execute(ClientHelper.IdentyUri(rRequest.Url.ToString()), rContainer);
            } catch (Exception ex) {
                iLog.Error(ex.Message);
                return true;
            }
        }
        /// <summary>
        /// 校验当前页面
        /// </summary>
        /// <param name="rUrlPattern"></param>
        /// <param name="rContainer"></param>
        /// <returns></returns>
        public static Boolean Execute(String rUrlPattern, Control rContainer) {
            XmlNode form = GetForm(rUrlPattern);
            StringBuilder sb = new StringBuilder();
            sb.Append("var " + OutputVarName + "=[");
            if (form == null) {
                iLog.Debug("没有为当前页面(" + rUrlPattern + ")配置validation内容");
                return true;
            }
            XmlNode node = null;
            String atServer="",type, id, val,pattern;
            for (int i = 0; i < form.ChildNodes.Count; i++) {
                node = form.ChildNodes[i];
                if (node.Attributes["type"] != null)
                    type = node.Attributes["type"].Value.ToLower();
                else
                    type = VdType.REQUIRED;
                if (node.Attributes["id"] == null) continue;
                id = node.Attributes["id"].Value;
                if(node.Attributes["server"]!=null)
                    atServer = node.Attributes["server"].Value;
                if (String.IsNullOrEmpty(atServer)) continue;
                val = GetValue(rContainer, id);
                if (val == null) continue;
                if (type == VdType.REQUIRED && String.IsNullOrEmpty(val)) {//必填
                    _Message = node.InnerText;
                    return false;
                } else if (type == VdType.REGEX && !String.IsNullOrEmpty(val)) {//正则
                    if (node.Attributes["pattern"] == null) return false;
                    pattern = node.Attributes["pattern"].Value;
                    if (!Regex.IsMatch(val, pattern)) {
                        _Message = node.InnerText;
                        return false;
                    }
                } else if (type == VdType.INTEGER && !String.IsNullOrEmpty(val)) {//整数
                    try {
                        Convert.ToInt32(val);
                    } catch {
                        _Message = node.InnerText;
                        return false;
                    }
                } else if (type == VdType.FLOAT && !String.IsNullOrEmpty(val)) {//浮点数
                    try {
                        Convert.ToDecimal(val);
                    } catch {
                        _Message = node.InnerText;
                        return false;
                    }
                } else if (type == VdType.DATETIME && !String.IsNullOrEmpty(val)) {//日期时间
                    try {
                        Convert.ToDateTime(val);
                    } catch {
                        _Message = node.InnerText;
                        return false;
                    }
                } else {
                    iLog.Debug("not implament validate method :"+type);
                }
            }
            _Message = "";
            return true;
        }

        public static String GetValue(Control rContainer, String rId) {
            Control ctrl = rContainer.FindControl(rId);
            if (ctrl != null) {
                if (ctrl is TextBox) {
                    return (ctrl as TextBox).Text;
                } else if (ctrl is DropDownList) {
                    return (ctrl as DropDownList).SelectedValue;
                } else if (ctrl is HiddenField) {
                    return (ctrl as HiddenField).Value;
                } else if (ctrl is Label) {
                    return (ctrl as Label).Text;
                } else if (ctrl is CheckBox) {
                    return (ctrl as CheckBox).Checked.ToString();
                } else if (ctrl is RadioButton) {
                    return (ctrl as RadioButton).Checked.ToString();
                } else {
                    iLog.Debug("unknown control :" + rId);
                }
            } else {
                iLog.Debug("control not found :" + rId);
            }
            iLog.Debug("control value not found :" + rId);
            return null;
        }
    }
}
